package edu.zzuli.common.security;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter;
import org.apache.commons.lang.StringUtils;
import org.springframework.jdbc.core.JdbcTemplate;

import edu.zzuli.common.Constants_core;

/**
 *
 */
public class CustomAuthenticationProcessingFilter extends AuthenticationProcessingFilter {
	
	private JdbcTemplate jdbcTemplate;
	
	public static final String ACEGI_SECURITY_FORM_CHECKCODE_KEY = "j_checkcode";

	public static final String ACEGI_SECURITY_FORM_CAID_KEY = "j_caid";

	public static final String ACEGI_SECURITY_FORM_AD_KEY = "j_aduser";

	public static final String ACEGI_SECURITY_FORM_KHEP_KEY = "iv-user";

	private String authenticationCodeFaileUrl;

	private String authenticationCaFaileUrl;

	private String authenticationCfFailureUrl;

	private String authenticationSybzFailureUrl;

	public Authentication attemptAuthentication(HttpServletRequest request) throws AuthenticationException {

		String username = obtainUsername(request);
		String password = obtainPassword(request);
		String caid = this.obtainCaid(request);
		String epdlh = this.obtainEpDlh(request);
		String aduser = this.obtainAdUser(request);
		if (StringUtils.isNotEmpty(epdlh)) {
			username = epdlh.toUpperCase();
			password = "0";
		}
		if (username == null) {
			username = "";
		}
		if (password == null) {
			password = "";
		}
		UsernamePasswordAuthenticationToken authRequest = null;
		if (caid == null || caid.length() == 0) {
			if (StringUtils.isNotEmpty(aduser)) {
				// ad登录
				this.checkCodeValide(request);
				authRequest = new CustomUsernameAuthenticationToken(aduser);
				request.getSession().setAttribute(
						ACEGI_SECURITY_LAST_USERNAME_KEY, username);

			} else {
				if ((epdlh == null || epdlh.length() == 0)) {
					this.checkCodeValide(request);
				}
				authRequest = new UsernamePasswordAuthenticationToken(username, password);
				// Place the last username attempted into HttpSession for views
				request.getSession().setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY, username);
			}

		} else {
			authRequest = new CustomUsernamePasswordAuthenticationToken(caid);
		}
		// Allow subclasses to set the "details" property
		setDetails(request, authRequest);
		return this.getAuthenticationManager().authenticate(authRequest);
	}

	@SuppressWarnings("unchecked")
	protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException {
		if (failed instanceof CustomAuthenticationException) {
			CustomAuthenticationException customAuthenticationException = (CustomAuthenticationException) failed;
			if (customAuthenticationException.getExcCode() == CustomAuthenticationException.CODE_CA) {
				try {
					request.setAttribute("errtype", String.valueOf(customAuthenticationException.getErrtype()));
					request.setAttribute("info", failed.getMessage());
					request.getRequestDispatcher(this.getAuthenticationCaFaileUrl()).forward(request, response);
				} catch (ServletException e) {
					e.printStackTrace();
				}
			} else if (customAuthenticationException.getExcCode() == CustomAuthenticationException.CODE_JYM) {
				this.sendRedirect(request, response, this.getAuthenticationCodeFaileUrl());
			} else {
				// 判断登录的错误类别1-帐号或密码错误，2-CA错误，3-与服务器的连接已断开，请重新登录，4-校验码不正确，5-登录重复，6-未审核通过
//				JdbcTemplate jdbcTemplate = (JdbcTemplate) SpringBeanUtil.getBean("jdbcTemplate");
				String sql = "select sfdl,sybz from gg_czyb where dlh='" + obtainUsername(request) + "'";

				List list = jdbcTemplate.queryForList(sql);
				if (list != null && list.size() > 0) {
					int ls_sfdl = Integer.parseInt(((Map) list.get(0)).get("SFDL").toString());
					int ls_sybz = Integer.parseInt(((Map) list.get(0)).get("SYBZ").toString());

					if (ls_sfdl == 1) {
						this.sendRedirect(request, response, this.getAuthenticationCfFailureUrl());
					} else if (ls_sybz != Constants_core.OPERATOR_VALID_BZ) {
						this.sendRedirect(request, response, this.getAuthenticationSybzFailureUrl());
					} else {
						this.sendRedirect(request, response, this.getAuthenticationFailureUrl());
					}
				} else {
					this.sendRedirect(request, response, this.getAuthenticationFailureUrl());
				}
			}
		} else {
			// 判断登录的错误类别1-帐号或密码错误，2-CA错误，3-与服务器的连接已断开，请重新登录，4-校验码不正确，5-登录重复，6-未审核通过
//			JdbcTemplate jdbcTemplate = (JdbcTemplate) SpringBeanUtil .getBean("jdbcTemplate");
			String sql = "select sfdl,sybz from gg_czyb where dlh='" + obtainUsername(request) + "'";

			List list = jdbcTemplate.queryForList(sql);
			if (list != null && list.size() > 0) {
				int ls_sfdl = 0;
				int ls_sybz = 0;
				try {
					ls_sfdl = Integer.parseInt(((Map) list.get(0)).get("SFDL").toString());
					ls_sybz = Integer.parseInt(((Map) list.get(0)).get("SYBZ").toString());
				} catch (Exception e) {

				}
				if (ls_sfdl == 1) {
					this.sendRedirect(request, response, this.getAuthenticationCfFailureUrl());
				} else if (ls_sybz != Constants_core.OPERATOR_VALID_BZ) {
					this.sendRedirect(request, response, this.getAuthenticationSybzFailureUrl());
				} else {
					this.sendRedirect(request, response, this.getAuthenticationFailureUrl());
				}
			} else {
				this.sendRedirect(request, response, this.getAuthenticationFailureUrl());
			}
			// super.unsuccessfulAuthentication(request, response, failed);
		}
	}

	protected String obtainCheckcode(HttpServletRequest request) {
		return request.getParameter(ACEGI_SECURITY_FORM_CHECKCODE_KEY);
	}

	protected void checkCodeValide(HttpServletRequest request) throws AuthenticationException {
		String checkcode = this.obtainCheckcode(request);
		if (checkcode == null) {
			checkcode = "";
		}
		String sessionCode = (String) request.getSession(true).getAttribute(Constants_core.RANDOM_CHECKCODE);
		if (sessionCode == null) {
			sessionCode = "";
		} else if (checkcode.equals("") || sessionCode.equals("") || !sessionCode.equals(checkcode)) {
			throw new CustomAuthenticationException("校验码不正确，登录失败！", CustomAuthenticationException.CODE_JYM);
		}
	}

	public String getAuthenticationCodeFaileUrl() {
		return authenticationCodeFaileUrl;
	}

	public void setAuthenticationCodeFaileUrl(String authenticationCodeFaileUrl) {
		this.authenticationCodeFaileUrl = authenticationCodeFaileUrl;
	}

	public String getAuthenticationCaFaileUrl() {
		return authenticationCaFaileUrl;
	}

	protected String obtainEpDlh(HttpServletRequest request) {
		return request.getHeader(ACEGI_SECURITY_FORM_KHEP_KEY);
	}

	public void setAuthenticationCaFaileUrl(String authenticationCaFaileUrl) {
		this.authenticationCaFaileUrl = authenticationCaFaileUrl;
	}

	public String obtainCaid(HttpServletRequest request) {
		String caid = (String) request.getSession(true).getAttribute(
				ACEGI_SECURITY_FORM_CAID_KEY);
		request.getSession(true).removeAttribute(ACEGI_SECURITY_FORM_CAID_KEY);
		return caid;
	}

	public String obtainAdUser(HttpServletRequest request) {
		String adid = (String) request.getSession(true).getAttribute(ACEGI_SECURITY_FORM_AD_KEY);
		request.getSession(true).removeAttribute(ACEGI_SECURITY_FORM_AD_KEY);
		return adid;
	}

	public String getAuthenticationCfFailureUrl() {
		return authenticationCfFailureUrl;
	}

	public void setAuthenticationCfFailureUrl(String authenticationCfFailureUrl) {
		this.authenticationCfFailureUrl = authenticationCfFailureUrl;
	}

	public String getAuthenticationSybzFailureUrl() {
		return authenticationSybzFailureUrl;
	}

	public void setAuthenticationSybzFailureUrl(
			String authenticationSybzFailureUrl) {
		this.authenticationSybzFailureUrl = authenticationSybzFailureUrl;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

}
